package cn.kgc.vue.shiro;

import cn.kgc.vue.entity.Permission;
import cn.kgc.vue.entity.RolePers;
import cn.kgc.vue.entity.UserRole;
import cn.kgc.vue.mapper.PermissionMapper;
import cn.kgc.vue.mapper.RoleMapper;
import cn.kgc.vue.mapper.RolePersMapper;
import cn.kgc.vue.mapper.UserRoleMapper;
import cn.kgc.vue.utils.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author: 课工场
 * @Version: v1.0  2023/8/9
 * @Description:
 */

public class CustomerRealm extends AuthorizingRealm {
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RolePersMapper rolePersMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }
    // 授权方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        Integer id = (Integer)principals.getPrimaryPrincipal();
        //根据用户id查找
        LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserRole::getUserId,id);
        List<Integer> roleId = userRoleMapper.selectList(wrapper).stream().map(s -> s.getRoleId()).collect(Collectors.toList());
        List<String> list = roleMapper.selectBatchIds(roleId).stream().map(s -> s.getRoleEn()).collect(Collectors.toList());
        //获取菜单的权限
        LambdaQueryWrapper<RolePers> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.in(RolePers::getRoleId,roleId);
        List<Integer> perId = rolePersMapper.selectList(wrapper1).stream().map(s -> s.getPerId()).collect(Collectors.toList());
        //根据perid
        LambdaQueryWrapper<Permission> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.in(Permission::getId,perId).eq(Permission::getIsMenu,2);
        List<String> permissionList = permissionMapper.selectList(wrapper2).stream().map(s -> s.getPermission()).collect(Collectors.toList());
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRoles(list);
        simpleAuthorizationInfo.addStringPermissions(permissionList);
        return simpleAuthorizationInfo;
    }
    // 认证方法  默认情况下  认证通过 会将用户信息 存储在session中  访问的是受限资源 被shiro提供的表单认证过滤器拦截
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        JwtToken jwtToken=(JwtToken) token;
        String token1 = jwtToken.getToken();
        //验证token
        JWTUtil.verifyToken(token1);
        //解析token
        Map<String, Object> claim = JWTUtil.getClaim(token1);
        Integer userId = (Integer) claim.get("userId");
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userId,token1,this.getName());
        return simpleAuthenticationInfo;
    }
}
